
//
// 121118 - AH - Created.
//

package org.japril.jutil.sol;

import java.io.CharArrayWriter;
import java.io.PrintWriter;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import java.util.Map;

import org.japril.jutil.JCollections;

/**
 * <p>
 *   Base class for 
 *   {@link Sol} implementations.
 * </p>
 * @author Arne Halvorsen (AH)
 */
public abstract class AbstractSol implements Sol 
{
  private final Map<String, List<Object>> m_objects=
    new HashMap<String, List<Object>>();

  // Specified in Sol.
  public List<String> getCategoryNames() 
  {
    return new ArrayList<String>(m_objects.keySet());
  }
  
  // Specified in Sol.
  public final <T> List<T> getLoaded(String cat, Class<? extends T> clazz)
  {
    if (cat==null)
    {
      throw new NullPointerException("cat");
    }
    if (clazz==null)
    {
      throw new NullPointerException("clazz");
    }
    
    List<Object> l=m_objects.get(cat);
    if (l==null) return new ArrayList<T>();
    
    return JCollections.findTypes(l, clazz);
  }

  /**
   * <p>
   *   Adds loaded.
   * </p>
   * @param cat Category loaded object belong to.
   * @param o   Loaded object.
   */
  protected final void addLoaded(String cat, Object o)
  {
    if (cat==null)
    {
      throw new NullPointerException("cat");
    }
    if (o==null)
    {
      throw new NullPointerException("o");
    }
    
    List<Object> l=m_objects.get(cat);
    if (l==null)
    {
      l=new ArrayList<Object>();
      m_objects.put(cat, l);
    }
    l.add(o);
  }
  
  @Override
  public String toString()
  {
    CharArrayWriter caw=new CharArrayWriter();
    PrintWriter pw=new PrintWriter(caw);
    
    for (Map.Entry<String, List<Object>> e : m_objects.entrySet())
    {
      String cat=e.getKey();
      List<Object> objects=e.getValue();
      pw.println("Category: "+cat);
      for (Object object : objects)
      {
        pw.println("  "+object);  
      }
    }
    
    pw.flush();
    return caw.toString();
  }
  
}
